import os.path

from flask import Blueprint, render_template, redirect, request, url_for, jsonify, session, g
from sqlalchemy import and_
from werkzeug.security import generate_password_hash, check_password_hash
from werkzeug.utils import secure_filename

from apps.article.model import Article_type, Article
from apps.user.model import User
from ext import db
from settings import Config

user_bp = Blueprint('user', __name__, url_prefix='/user')

# 钩子函数筛选的路径
required_login_list = ['/user/show']
# 允许上传的文件类型
allowed_extensions = ['jpg', 'gif', 'png', 'bmp']


# 在正常执行代码前中后，强行插入执行一段你想执行的代码功能，叫做钩子函数
# before_app_first_request:第一次访问服务器时执行的钩子函数
@user_bp.before_app_first_request
def first_request():
    print('before_app_first_request')


# before_app_request:每次访问服务器前都执行的钩子函数,可以当成"滤网"使用
@user_bp.before_app_request
def before_request():
    # 设置全局变量article_types
    article_types = Article_type.query.all()
    g.article_types = article_types
    if request.path in required_login_list:
        uid = session.get('uid')
        if not uid:
            return render_template('user/login.html', article_types=g.article_types, msg='请登录')
        else:
            # flask.g,flask自带的全局变量,当成一个对象来使用,存活周期是一次请求
            user = User.query.get(uid)
            g.user = user
    else:
        uid = session.get('uid')
        if uid:
            user = User.query.get(uid)
            g.user = user
        else:
            g.user = ''


# 定义一个过滤器,用于转码二进制文本
@user_bp.app_template_filter('decode')
def content_decode(content):
    content = content
    return content[0:150]


@user_bp.app_template_filter('decode_detail')
def content_decode_detail(content):
    # content = content.decode('utf-8')
    content = content
    return content


@user_bp.route('/')
def index():
    page = request.args.get('page')
    if not page:
        page = 1
    # 实现分页就要用到paginate()
    pagination = Article.query.order_by(-Article.pdatetime).paginate(page=int(page), per_page=3)
    if g.user:
        return render_template('user/index.html', user=g.user, article_types=g.article_types, pagination=pagination)
    else:
        return render_template('user/index.html', article_types=g.article_types, pagination=pagination)


@user_bp.route('register', methods=['POST', 'GET'])
def user_register():
    if request.method == 'POST':
        username = request.form.get('username')
        password = request.form.get('password')
        repassword = request.form.get('repassword')
        phone = request.form.get('phone')
        email = request.form.get('email')
        if password == repassword:
            users = User.query.filter(User.isdelete == False).all()
            for user in users:
                if user.username == username:
                    return render_template('user/register.html', article_types=g.article_types, msg='用户名已存在')
            user = User()
            user.username = username
            user.password = generate_password_hash(password)
            user.phone = phone
            user.email = email
            db.session.add(user)
            db.session.commit()
            return redirect(url_for('user.index'))
        else:
            return render_template('user/register.html', article_types=g.article_types, msg='两次密码不一致!')
    else:
        return render_template('user/register.html', article_types=g.article_types)


@user_bp.route('/phone_check')
def phone_check():
    phone_num = request.args.get('phone_num')
    user = User.query.filter(and_(User.phone == phone_num, User.isdelete == False)).all()
    if len(user) > 0:
        return jsonify(code=400, msg='手机号已注册')
    else:
        return jsonify(code=200, msg='手机号无误')


@user_bp.route('show')
def user_show():
    uid = session.get('uid')
    users = User.query.filter(User.isdelete == False).all()
    if uid:
        return render_template('user/show.html', users=users, user=g.user, article_types=g.article_types)
    else:
        return render_template('user/show.html', users=users)


@user_bp.route('delete')
def user_delete():
    uid = request.args.get('uid')
    user = User.query.get(uid)
    user.isdelete = True
    db.session.commit()
    return redirect(url_for('user.user_show'))


@user_bp.route('/update', methods=['POST', 'GET'])
def user_update():
    if request.method == 'POST':
        password = request.form.get('password')
        email = request.form.get('email')
        # 只要有图片上传,获取方式就必须用request.files.get()
        icon = request.files.get('icon')
        # 获取文件名
        icon_name = icon.filename
        if icon_name.rsplit('.')[-1] in allowed_extensions:
            # 将文件名格式化,转换成安全的文件名,保证文件名符合python命名规则
            secure_icon_name = secure_filename(icon_name)
            icon_path = os.path.join(Config.UPLOAD_ICON_DIR, secure_icon_name)
            # 保存到项目中
            icon.save(icon_path)
            # 保存到数据库中
            user = g.user
            user.password = generate_password_hash(password)
            user.email = email
            user.icon = os.path.join('image/upload/icon/', secure_icon_name)
            db.session.commit()
            return redirect(url_for('user.user_show'))
        else:
            return render_template('user/update.html', user=g.user, article_types=g.article_types, msg='请上传图片文件！')
    else:
        uid = request.args.get('uid')
        user2 = User.query.get(uid)
        return render_template('user/update.html', user=g.user, article_types=g.article_types, user2=user2)


@user_bp.route('/login', methods=['POST', 'GET'])
def user_login():
    if request.method == 'POST':
        username = request.form.get('username')
        password = request.form.get('password')
        users = User.query.filter(and_(User.username == username, User.isdelete == False)).all()
        for user in users:
            if check_password_hash(user.password, password):
                session['uid'] = user.id
                return redirect(url_for('user.index'))
            else:
                return render_template('user/login.html', article_types=g.article_types, msg='用户名或密码错误')
    else:
        return render_template('user/login.html', article_types=g.article_types)


@user_bp.route('/logout')
def user_logout():
    session.clear()
    return redirect(url_for('user.index'))
